(function (global) {
  var dataURLtoFile = (dataurl, filename) => {
    var arr = dataurl.split(",");
    var mime = arr[0].match(/:(.*?);/)[1];
    var bstr = window.atob(arr[1]);
    let n = bstr.length;
    var u8arr = new Uint8Array(n);
    while (n) {
      u8arr[n - 1] = bstr.charCodeAt(n - 1);
      n -= 1; // to make eslint happy
    }
    return new File([u8arr], filename, { type: mime });
  };

  var getLocalImg = function (localId) {
    // Util.Toast(localId);
    return new Promise((resolve, reject) => {
      wx.getLocalImgData({
        localId: localId,
        success: (res) => {
          var localData = res.localData;
          let imageBase64 = "";
          if (localData.indexOf("data:image") == 0) {
            //苹果的直接赋值，默认生成'data:image/jpeg;base64,'的头部拼接
            imageBase64 = localData;
          } else {
            //此处是安卓中的唯一得坑！在拼接前需要对localData进行换行符的全局替换
            //此时一个正常的base64图片路径就完美生成赋值到img的src中了
            imageBase64 =
              "data:image/jpeg;base64," + localData.replace(/\n/g, "");
          }
          // Util.Toast("begin upload");
          resolve(dataURLtoFile(imageBase64, `${Date.now()}.png`));
        },
      });
    });
  };

  var getAllLocalImgs = function (localIds) {
    var promises = Promise.all(
      localIds.map(function (localId) {
        return getLocalImg(localId);
      })
    );
    return promises;
  };
  global.parseQueryString = function (search) {
    // 去掉开头的 '?'，如果存在
    var queryString = decodeURIComponent(
      search.startsWith("?") ? search.slice(1) : search
    );

    // 将查询字符串分割成键值对数组
    var pairs = queryString.split("&");

    // 将键值对数组转换为对象
    var queryObject = pairs.reduce((acc, pair) => {
      var [key, value] = pair.split("=");
      // 解码键和值，并处理 undefined 值
      var decodedKey = decodeURIComponent(key || "");
      var decodedValue = decodeURIComponent(value || "");

      if (decodedKey) {
        // 处理同一键的多个值，存储为数组
        if (acc[decodedKey]) {
          acc[decodedKey] = [].concat(acc[decodedKey], decodedValue);
        } else {
          acc[decodedKey] = decodedValue;
        }
      }
      return acc;
    }, {});

    return queryObject;
  };

  global.searchConfig = global.parseQueryString(window.location.search);

  global.signConfig = searchConfig.sign && JSON.parse(searchConfig.sign);
  global.routeConfig = searchConfig.config && JSON.parse(searchConfig.config);

  global.NativeUtil = {
    _Callback: {},
    /**
     * [调用原生方法]
     * @param  {[type]}   name     [原生方法名]
     * @param  {Function} callback [成功之后的回调]
     * @param  {[type]}   param    [原生插件需要的参数]
     * @return [type]              [description]
     */
    use: function (name, callback, param) {
      var args = [].slice.call(arguments);
      console.log(args);
      if (this[name]) {
        if (args.length > 1) {
          var callbackId = this._genetateId(name);
          this._Callback[callbackId] = callback;
        }
        if (args.length > 2) {
          return this[name](callbackId, param);
        } else if (args.length == 2) {
          return this[name](callbackId);
        } else if (args.length == 1) {
          return this[name]();
        }
      }
    },
    /**
     *  生成回调id
     * @param  {[type]} name [调用的原生方法名]
     * @return [type]        [回调id]
     */
    _genetateId: function (name) {
      var callbackId;
      callbackId = name + "CB" + ("" + Date.now()).slice(-7);
      return callbackId;
    },
    /**
     * 用于原生回调的处理方法
     * @param  {[type]} callbackId [每一个回调会有自己id]
     * @param  {[type]} result     [原生返回的结果]
     * @return [type]              [description]
     */
    NativeCallback: function (callbackId, result) {
      console.log(result);
      if (this._Callback[callbackId]) {
        this._Callback[callbackId](result);
        delete this._Callback[callbackId];
      } else {
        console.info("NativeCallback can't found callbackId");
      }
    },
    /**
     * 显示隐藏loader
     * @return [type] [description]
     */
    toggleProgressDialog: function (type) {
      // if (window.wx&&window.wx.miniProgram) {
      //   try {
      //     window.wx&&window.wx.miniProgram.toggleProgressDialog(type);
      //   } catch (e) {
      //     console.log(e);
      //   }
      // }
    },
    /**
     * 当前链接的wifi
     */
    getConnectionInfo: function () {},
    /**
     * 周边wifi
     * @return [type] [description]
     */
    getScanResults: function () {},
    /**
     * 获取设备信息
     * @return [string] [设备id]
     */
    getDeviceInfo: function () {
      if (window.wx) {
        try {
          var deviceInfo = window.wx.getDeviceInfo();
        } catch (e) {
          return {};
        }
        if (deviceInfo) {
          return JSON.parse(deviceInfo);
        }
      } else {
        return {
          deviceId: "868904020579706",
          model: "m2",
          system: "android",
        };
      }
    },
    /**
     * 原生插件成功之后的callback
     * @param  {[type]} callbackId [用于获取回调方法的id]
     * @param  {[type]} result     [原生方法返回值]
     * @return [type]              [description]
     */

    /**
     * 获取当前应用版本号
     * @return [type] [description]
     */
    getAppVersion: function () {},
    /**
     * 关闭webview
     * @return [type] [description]
     */
    close: function () {
      if (window.wx) {
        try {
          window.wx.closeWindow();
        } catch (e) {
          console.log(e);
        }
      }
    },
    /**
     * 获取经纬度
     * @return [type] [返回经纬度]
     */
    getLatLng: function (callbackId) {
      if (window.wx) {
        try {
          wx.getLocation({
            type: "wgs84", // 默认为wgs84的gps坐标，如果要返回直接给openLocation用的火星坐标，可传入'gcj02'
            success: function (res) {
              var latitude = res.latitude; // 纬度，浮点数，范围为90 ~ -90
              var longitude = res.longitude; // 经度，浮点数，范围为180 ~ -180。
              var speed = res.speed; // 速度，以米/每秒计
              var accuracy = res.accuracy; // 位置精度
              var position = global.wgs84ToBd09(res.longitude, res.latitude);
              res.latitude = position[1];
              res.longitude = position[0];
              global.NativeUtil.NativeCallback(callbackId, res);
            },
            fail: function (e) {
              console.log(e.meaasge);
            },
          });
        } catch (e) {
          alert(e.meaasge);
          console.log(e);
        }
      }
    },
    getDistance: function (callbackId, param) {
      var distance = -1;
      if (window.wx) {
        try {
          distance =
            window.wx &&
            window.wx.getDistance(
              JSON.stringify(param.p1),
              JSON.stringify(param.p2)
            );
        } catch (e) {
          return distance;
          console.log(e);
        }
      }
      return distance;
    },
    // 获取用户基本信息
    getUserInfo: function (callback) {
      var userinfo;
      if (window.wx) {
        try {
          userinfo = window.wx.getUserInfo();
        } catch (e) {
          return {};
        }
        if (userinfo) {
          return JSON.parse(userinfo);
        }
      }
    },
    /**
     * 获取用户签名信息用于验证
     * @return [json] [用户签名信息]
     */
    getSign: function () {
      if (global.signConfig) {
        return global.signConfig;
      } else {
        sign = {};
        return sign;
      }
    },
    getSignStr: function () {
      var param = function (obj) {
        var query = "",
          name,
          value,
          fullSubName,
          subName,
          subValue,
          innerObj,
          i;

        for (name in obj) {
          value = obj[name];
          if (value instanceof Array) {
            for (i = 0; i < value.length; ++i) {
              subValue = value[i];
              fullSubName = name + "[]";
              innerObj = {};
              innerObj[fullSubName] = subValue;
              query += param(innerObj) + "&";
            }
          } else if (value instanceof Object) {
            for (subName in value) {
              subValue = value[subName];
              fullSubName = name + "[" + subName + "]";
              innerObj = {};
              innerObj[fullSubName] = subValue;
              query += param(innerObj) + "&";
            }
          } else if (value !== undefined && value !== null)
            query +=
              encodeURIComponent(name) + "=" + encodeURIComponent(value) + "&";
        }

        return query.length ? query.substr(0, query.length - 1) : query;
      };
      return param(global.signConfig);
    },
    // 获取初始化页面参数
    getUrlParams: function () {
      // 先取缓存，再去原生最后取假数据
      var router = window.sessionStorage.getItem("routerconfig");
      if (router) {
        window.sessionStorage.removeItem("routerconfig");
        return JSON.parse(router);
      }
      if (routeConfig) {
        return routeConfig;
      }
      return router;
    },

    /**
     * 时间选择插件
     * @param  {[type]} callbackId [用于回调的id]
     * @param  {[type]} type       [选择时间类型]
     * @return [type]              [description]
     */
    Datepicker: function (callbackId, type) {
      if (window.wx) {
        try {
          window.wx.pickDate(callbackId, type);
        } catch (e) {
          console.log(e);
        }
      }
    },
    /**
     * 图片预览
     * @param  {[type]} urls [需要预览的图片]
     * @return [type]        [description]
     */
    photoPreview: function (callbackId, param) {
      if (window.wx) {
        try {
          param.data = param.data.split("|").map(function (img) {
            return (
              openApi.previewshowimg +
              "?fileName=" +
              img +
              "&" +
              NativeUtil.getSignStr()
            );
          });

          return window.wx.previewImage({
            urls: param.data,
            current: param.data[param.index],
            // param.showbtn
          });
        } catch (e) {
          console.log(e);
        }
      }
    },
    /**
     * 调用默认浏览器
     * @url  {[type]} string [打开的地址]
     * @return [type]        [description]
     */
    openUrl: function (callbackId, url) {
      if (window.wx) {
        try {
          return window.wx.openUrl(url);
        } catch (e) {
          console.log(e);
        }
      }
    },

    attachPreview: function (callbackId, url) {
      if (window.wx) {
        try {
          return window.wx.attachPreview(url);
        } catch (e) {
          console.log(e);
        }
      }
    },
    /**
     * 选择与上传图片
     * @param  {[type]} callbackId [用于回调]
     * @param  {[type]} num        [可以选几张]
     * @param  {[type]} url        [上传地址]
     * @return [type]     1：相册｜0拍照         [description]
     */
    choosePhoto: function (callbackId, param) {
      if (window.wx) {
        try {
          wx.chooseImage({
            count: param.num > 9 ? 9 : param.num,
            sourceType: ["album", "camera"],
            mediaType: ["image"],
            success: (chooseResult) => {
              getAllLocalImgs(chooseResult.localIds)
                .then(function (list) {
                  return Promise.all(
                    list.map(function (imgData) {
                      return uploadImage(imgData);
                    })
                  );
                })
                .then(function (imgs) {
                  global.NativeUtil.NativeCallback(callbackId, imgs.join("|"));
                });
            },
          });
        } catch (e) {
          alert(JSON.stringify(e));
        }
      }
    },
    /**
     * 确认框
     * @param  {[type]} info       [确认信息]
     * @param  {[type]} callbackId [成功回调]
     * @param  {[type]} title      [提示头部]
     * @return [type]              [description]
     */
    confirm: function (callbackId, param) {
      if (window.wx) {
        try {
          global.NativeUtil.NativeCallback(callbackId);
          // return window.wx.confirm(param.title, param.info, callbackId)
        } catch (e) {
          console.log(e);
        }
      } else {
        window.confirm(info);
      }
    },
    beep: function () {
      if (window.wx) {
        try {
          // return window.wx.playVoice();
        } catch (e) {
          console.log(e);
        }
      }
    },
    /**
     * 提示框
     * @param  {[type]} title [提示头]
     * @param  {[type]} info  [提示信息]
     * @return [type]         [description]
     */
    alert: function (callbackId, param) {
      if (window.wx) {
        try {
          return Util.Toast(param.title);
        } catch (e) {
          console.log(e);
        }
      } else {
        Util.Toast(info);
      }
    },
    /**
     * 列表更新
     * @return [type] [description]
     */
    updateProcess: function () {
      if (window.wx) {
        wx.miniProgram.navigateBack()
      }
    },
    /**
     * 调用原生登录
     * @return [type] [description]
     */
    login: function () {
      if (window.wx) {
        return wx.miniProgram.navigateBack()
      }
    },
  };
  // 复写cordova插件
  navigator.notification = {
    confirm: function (info, callback, title) {
      var param = {
        info: info,
        title: title,
      };
      global.NativeUtil.use("confirm", callback, param);
    },
    alert: function (title, info) {
      var param = {
        info: info,
        title: title,
      };
      global.NativeUtil.use("alert", null, param);
    },
    beep: function () {
      global.NativeUtil.use("beep");
    },
  };

  global.getWXConfig = function () {
    var myHeaders = new Headers();
    myHeaders.append("Content-Type", "application/json");
    var url = openApi.ip + "/api/wx/jssdk.do";
    var options = {
      method: "POST",
      // mode:"no-cors",
      headers: myHeaders,
      body: JSON.stringify({
        ...window.signConfig,
        req: {
          paramMap: {
            // pageUrl: "http://192.168.0.195:9001/",
            pageUrl: window.location.href.split("#")[0],
          },
        },
        nonce: Date.now().toString(),
        appId: "SMALL_FRONT_MANAGE",
      }),
    };
    try {
      return fetch(url, options)
        .then((res) => res.json())
        .then((data) => {
          if (data && data.res) {
            var script = document.createElement("script");
            script.type = "text/javascript";
            // 设置 script 标签的内容
            var scriptstr = data.res?JSON.parse(data.res):"";
            script.textContent = scriptstr;
            // 将 script 标签插入到文档的 <head> 或 <body>
            document.body.appendChild(script);
          }
        });
    } catch (error) {
      console.error(error);
    }
  };

  var uploadImage = function (formdata) {
    return new Promise((resolve, reject) => {
      var formData = new FormData();
      formData.append("img", formdata, formdata.name);
      fetch(openApi.uploadUrl + "?" + global.NativeUtil.getSignStr(), {
        method: "POST",
        body: formData,
        headers: {
          Accept: "*",
        },
      })
        .then((res) => res.json())
        .then(function (data) {
          // Util.Toast(`upload succsee${data.code}`);
          if (data.code === 1) {
            resolve(data.data.imgName);
          }
        })
        .catch((e) => {
          reject(e.message);
          // Util.Toast(`upload file${e.message}`);
        });
    });
  };
})(window);
